I gadgets Nel mezzo del cammin del nostro corso su Intuition siamo giunti ad uno degli argomenti più importanti: i gadget. I bottoni, come vengono solitmante tradotti, sono dei pulsanti sullo schermo: l'utente infatti posizionandosi su di essi (identificati normalmente come rettangoli con aspetto 3D) e cliccando con il mouse attiva un'operazione, proprio come un pulsante; esistono due diverse categorie di gadget: di sistema e dell'applicazione; i primi li abbiamo già visti e utilizzati, sono infatti quelli già definiti dal sistema (gadget di profondità, di cambiamento di grandezza, di chiusura ecc.), i secondi sono definiti ed usati interamente dall'applicazione. I gadget possono essere divisi anche in quattro tipi, a seconda del funzionamento e delle caratteristiche: Gadget booleani (o bottoni) Sono gadget che funzionano semplicemente cliccandovi sopra e che una volta selezionati eseguono un'operazione. Gadget proporzionali Questo tipo di gadget sono come delle manopole che permettono di indicare uno fra diversi possibili valori; ad esempio gli slider per posizionare l'immagine nel MultiView. Gadget stringa Sono gadget che, venendo selezionati dall'utente, permettono di inserire un testo. Gadget custom I gadget custom sono una forma più generale di gadget che permettono di realizzare diversi tipi di funzioni e quindi risultano più flessibili di quelli visti. Ogni gadget viene attivato quando l'utente clicca all'interno di una precisa regione specificata dall'applicazione, denominata select box; quando il gadget viene selezionato la sua immagine cambia per indicare all'utente di essere stato attivato; questa operazione viene denominata highlighting; un gadget può essere abilitato (quindi utilizzabile dall'utente) o disabilitato (quindi non utilizzabile); la disabilitazione viene indicata all'utente mediante il mascheramento del gadget con un pattern a griglia. Un gadget di applicazione viene creato dichiarando ed inizializzando la struttura Gadget definita in "intuition/intuition.h"; Intuition avvisa l'applicazione sulla seleziona da parte dell'utente di un suo gadget mediante IDCMP_GADGETUDOWN e IDCMP_GADGETUP; il primo messaggio viene inviato appena l'utente seleziona con il pulsante sinistro del mouse il gadget, il secondo viene invece inviato quando l'utente rilascia il pulsante sul gadget; ambedue i messaggi hanno memorizzato nel campo IAddress l'indirizzo del gadget che è stato attivato. I gadget appaiono sempre in una finestra o in un requester; possono essere creati all'apertura della finestra, o essere inseriti e rimossi successivamente; possono essere posti in un qualsiasi punto della finestra, anche sui bordi; la finestra, all'apertura, modifica automaticamente la grandezza dei bordi per contenere interamente i gadget inseriti su essi; la grandezza di un gadget può essere fissa o relativa alla grandezza della finestra; la posizione di un gadget è normalmente relativa per la cordinata x al bordo sinistro e per la cordinata y al bordo superiore della finestra, ma può essere relativa anche agli altri bordi. Per creare una serie di gadget da agganciare alla finestra occorre definire e inizializzare una serie di strutture Gadget, facendo bene attenzione di prole in lista mediante il puntatore NextGadget, esempio: struct Gadget MioGad1 = { NULL, ... }; struct Gadget MioGad2 = { &MioGad1, ... }; struct Gadget MioGad3 = { &MioGad2, ... }; In realtà non risulta necessario porli in lista se si desidera inserirli o rimuoverli nella finestra una volta aperta, individualmente (vale a dire uno per volta) mediante AddGadget() e RemoveGadget(); se si desidera però inserirli tutti insieme o all'apertura della finestra o successivamente, occorre metterli in lista così come mostrato e far riferimento al primo elemento di quest'ultima che, nel nostro caso è MioGadg3 (attenzione è MioGad3 che punta a MioGad2 il quale punta a sua volta a MioGad1 che interrompe la lista con NULL); per inserirli all'apertura della finestra bisogna porre il puntatore al primo gadget della lista nel tag WA_Gadget in OpenWindowTagList; se desiderate inserirli o rimuoverli successivamente all'apertura della finestra bisogna utilizzare la funzione pos = AddGList(finestra,gadget,posizione,numgad,requester); dove "finestra" è il puntatore alla finestra in cui inserire i gadgets; "gadget" è il puntatore al primo gadget della lista; "posizione" è la posizione nella lista generale dei gadgets della finestra o del requester, in cui inserire i gadget (con ~0 si inseriscono i gadgets alla fine della lista); "numgad" è il numero di gadgets da inserire; "requester" è il puntatore al requester in cui inserire i gadgets (se non è utilizzato "finestra"); il valore ritornato "pos" indica la posizione in cui i gadgets sono stati inseriti nella lista generale. Per rimuivere una lista di gadgets occorre utilizzare la funzione pos = RemoveGList(finestra,gadget,numgad); dove i parametri assumono gli stessi significati descritti in AddGList() eccetto che per "pos" che indica la posizione del primo gadget della lista che è stato rimosso (vale -1 se il gadget non è stato trovato). Non bisogna mai modificare gli attributi dei gadgets mentre sono inseriti nella finestra; bisogna rimuoverli, modificarli e poi reinserirli con le funzioni appena viste. Ogni gadget è solitamente identificato con un'immagine in modo che l'utente possa riconoscerlo e attivarlo; intuition permette di associare ad un gadget una serie di informazioni grafiche in diversi modi; il programmatore può decidere se utilizzare come immagine del gadget, un'immagine bitmap; in questo caso bisogna inizializzare una struttura Image con i bitmap dell'immagine, inserirne l'indirizzo nel campo GadgetRender della struttura Gadget del gadget da creare, e impostare il flag GFLG_GADGIMAGE nel campo Flags sempre della struttura Gadget. Un'alternativa all'utilizzo dell'immagine bitmap consiste nell'utilizzo di un bordo; con bordo si intende una serie di linee che possono avere diverso colore; solitamente questa tecnica viene utilizzata per creare i "bordi" del gadget e per utilizzarla bisogna inizializzare una struttura Border con i dati delle linee, passare il puntatore della struttura nel campo GadgetRender del gadget e non impostare il flag GFLG_GADGIMAGE (da questo si capisce che i bordi e le immagini non possono essere utilizzati insieme). Ad ogni gadget può essere associato insieme ad una delle due forme grafiche appena viste, un testo; per far questo bisogna inizializzare la struttura IntuiText con il testo e passarne l'indirizzo nel campo GadgetText del gadget. Il programmatore può decidere anche di non associare alcun grafico o testo al gadget, perché l'applicazione possiede già informazioni grafiche sufficienti o perché potrebbe non averne bisogno; un classico esempio consiste in un editor di testi, dove viene utilizzato un unico gadget che copra tutta la finestra testo; in questo modo l'applicazione viene avvisata quando l'utente clicca nella finestra testo e può agire di conseguenza (riposizionare il cursore o selezionare un blocco di testo). Normalmente quando l'utente seleziona un gadget, questo cambia la propria immagine per indicare di essere in fase di selezione (fase di Highlighting); ci sono diversi modi per realizzare la fase grafica di selezione: - Evidenziazione mediante complemento del colore - Evidenziazione disegnando un box - Evidenziazione mediante un'altra immagine o bordo - Nessuna evidenziazione L'evidenziazione mediante il complemento del colore, consiste nell'invertire bit a bit il codice dei colori del rettangolo di selezione; questa tecnica si ottiene attivanno il flag GFLG_GADGHCOMP nel campo Flags e risulta molto semplice da utilizzare; se i colori vengono impostati oculatamente l'effetto grafico può risultare qualitativamente elevato. L'evidenziazione mediante il disegno di un box, consiste nel far disegnare ad intuition un rettangolo che contorni il gadget; questa evidenziazione si attiva impostando il flag GFLG_GADGHBOX nel campo Flags. L'evidenziazione mediante immagine o bordo consiste nell'utilizzare un'altra immagine (se il disegno del gadget era costituito da un'immagine) o un altro bordo (se il rendering del gadget era un bordo) che indichino l'immagine selezionata; ovviamente bisogna inizializzare le relative strutture (Image nel primo caso e Border nel secondo) e passare il relativo puntatore nel campo SelectRender del gadget; bisogna anche specificare il flag GFLG_GADGHIMAGE nel campo Flags. Grandezza e posizione del gadget La posizione e le dimensioni del box di selezione del gadget sono definite dai campi LeftEdge, TopEdge, Width e Height del gadget, che indicano la posizione in pixels relativa ai bordi della finestra, e l'ampiezza e altezza sempre in pixels. L'immagine ed il testo del gadget sono sempre relativi alla posizione del gadget, per cui spostando quest'ultimo anche la sua immagine lo seguirà; la grandezza dell'immagine non è relativa alla grandezza del gadget, per cui se la dimensione del gadget viene modificata, bisogna effettuare il cambiamento nell'immagine oppure utilizzare un gadget BOOPSI. Come sopra accennato, la posizione è relativa ai bordi della finestra; normalmente LeftEdge è relativo al bordo sinistro (quindi si utilizzano valori positivi) e TopEdge è relativo al bordo superiore (si utilizzano valori positivi); vi è però la possibilità di rendere la posizione relativa verso gli altri bordi (un gadget che fa comunemente uso di ciò è quello di cambiamento della grandezza della finestra, che si trova sempre in basso a destra); se si vuole rendere LeftEdge relativo al bordo di destra (quindi si usano normalmente valori negativi) bisogna impostare il flag GFLG_RELRIGHT nel campo Flags; per rendere TopEdge relativo al bordo inferiore (si utilizzano valori negativi) si deve impostare il flag GFLG_RELBOTTOM nel campo Flags. Normalmente le dimensioni sono fisse, ma possono essere rese relative alla grandezza della finestra; bisogna impostare il flag GFLG_RELWIDTH per rendere l'ampiezza del gadget relativa all'ampiezza della finestra e GFLG_RELHEIGHT per fare lo stesso con l'altezza (possono anche essere usati singolarmente); il sistema per calcolare l'ampiezza (o altezza) del gadget, consiste nel sommare il valore del campo Width (o Height) del gadget con il valore dell'ampiezza (o altezza) della finestra; in tal caso si utilizzano normalmente valori negativi. Si può decidere di posizionare i gadget sui bordi della finestra; in questa evenienza il sistema dimensionerà opportunamente la grandezza del bordo, per contenere tutti i gadget presenti sullo stesso; per indicare ad Intuition quali gadget si trovano sui bordi e di quali bordi si tratta, bisogna impostare i flags GACT_RIGHTBORDER (il gadget è nel bordo destro), GACT_LEFTBORDER (bordo sinistro), GACT_TOPBORDER (bordo superiore), GACT_BOTTOMBORDER (bordo inferiore) nel campo Activation del gadget. Attenzione che Intuition adatterà la grandezza dei bordi solo all'apertura della finestra; per cui i gadget per i bordi devono gia essere tutti presenti nella lista dei gadgets passata ad OpenWindowTagList e se venissero aggiunti o rimossi successivamente, Intuition non modificherà la grandezza dei bordi. Alcune volte può capitare che il bordo non copra a livello grafico tutti i gadgets sui bordi, per ovviare a questo inconveniente basta creare un gadget "fantasma" (vale a dire senza immagine e che non serve a nulla) posto sul bordo e inserirlo in fondo alla lista dei gadget e, modificandone posizione e grandezza si potrà controllare la dimensione del bordo; si consiglia di rendere relativi al bordo destro i gadget presenti su tale bordo, e di rendere relativi al bordo inferiore i gadget presenti sullo stesso bordo; i gadget potrebbo essere presenti su due bordi contemporaneamente (se il gadget è in un angolo della finestra) per cui possono essere attivati due GACT_xxxBORDER adiacenti. Come in ogni altro mezzo di comunicazione di Intuition anche i Gadget indicano all'applicazione di essere stati attivati mediante messaggi IDCMP; possiamo avere due comunicazioni, una indicante che l'utente ha selezionato (ma non rilasciato) il gadget (IDCMP_GADGETDOWN) e l'altra in cui l'utente lo ha rilasciato (IDCMP_GADGETUP); oltre ad indicare ad Intuition quali dei due tipi (o tutte e due) di messaggi ricevere, bisogna indicare per ogni singolo gadget quale azione deve compiere quest'ultimo una volta selezionato; impostando il flag GACT_IMMEDIATE nel campo Activation del gadget, Intuition invierà un IDCMP_GADGETDOWN all'applicazione quando l'utente selezionerà il gadget; impostando il flag GACT_RELVERIFY sempre nel campo Activation, Intuition invierà il messaggio IDCMP_GADGETUP all'applicazione quando l'utente rilascierà il gadget; se l'utente muove il puntatore al di fuori del gadget (mentre è attivato) e rilascia il pulsante, Intuition invierà un messaggio di tipo IDCMP_MOUSEBUTTONS. Per comprendere quale gadget ha generato il messaggio, basta controllare il campo IAddress di IntuiMessage, in cui è contenuto l'indirizzo della struttura Gadget del gadget che ci interessa; una volta ottenuto tale puntatore, si controlla il contenuto del campo GadgetID del gadget che contiene il codice identificatore di quest'ultimo, anche se basterebbe il semplice indirizzo (attenzione, prelevare il GadgetID solo quando si è certi che il messaggio è di tipo IDCMP_GADGETDOWN o IDCMP_GADGETUP). Vi è la possibilità di essere informati sullo spostamento del mouse, mentre un gadget è selezionato; questo può risultare utile in caso di gadget proporzionali o in altri casi particolari; per essere ratificati di spostamenti del mouse, bisogna attivare il flag GACT_FOLLOWMOUSE nel campo Activation del gadget; Intuition invierà messaggi di tipo IDCMP_MOUSEMOVE ad ogni movimento del mouse (in questo tipo di messaggi non viene memorizzato il codice del gadget, quindi non lo si deve prelevare); nel caso di gadget booleani bisogna sempre specificare GACT_RELVERIFY per essere informati dei movimenti del mouse. Attivazione e disattivazione dei gadgets Un gadget può essere disattivato (quindi non utilizzabile dall'utente) con effetto a video indicato da un pattern a scacchiera che si sovrappone all'immagine del gadget; l'applicazione può indicare di aprire dei gadget già deselezionati, mediante GFLG_DISABLED; durante tutto il periodo di attività non possono essere attivati o disattivati agendo su questo flag, ma devono essere utilizzate le seguenti funzioni: OnGadget(gadget, finestra, requester); OffGadget(gadget, finestra, requester); Dove gadget è il puntatore alla struttura gadget del gadget da abilitare o disabilitare; finestra è il puntatore alla finestra a cui il gadget è agganciato; requester è il puntatore al requester se il gadget è invece agganciato ad un requester. I gadget booleani Torniamo a prlare di gadgets booleani, in realtà avete già tutti gli elementi per crearli ma mancano ancora alcuni aspetti; come già detto i gadget booleani sono come dei bottoni che implementano operazioni del tipo ON/OFF o Si/No; selezionandone uno questo funziona come un pulsante che attiverà un'operazione; vi è la possibilità di utilizzarli come "interruttori" cioè come indicatori di uno stato attivo/disattivo impostando GACT_TOGGLESELECT nel campo Activation della struttura Gadget, ma questo è stato già visto. La caratteristica non ancora spiegata è il mascheramento (naturalmente non quello carnevalesco); normalmente il gadget ha forma rettangolare e le operazioni di selezione e di illuminazione (highlighting) vengono impostate su questa zona rettangolare; può accadere di volere forme diverse da quella rettangolare (come quella ovale) e per questo è stato realizzato il mascheramento; nel mascheramento il programmatore mette a disposizione di intuition una maschera (immagine di un bitplane della stessa grandezza del gadget) dove i bit ad 1 indicano i pixels effettivamente appartenenti al gadget; il mascheramento funziona per la selezione (se l'utente clicca sul gadget in un punto in cui la maschera è 0, allora intuition non selezionerà il gadget) e per l'illuminazione a complemento (il complemento dei bit dell'immagine verrà realizzato solo per quelli in cui la maschera ha 1), il mascheramento non funziona però per l'immagine; questo vuol dire che nel rinfresco dell'immagine verrà ridisegnato tutto il rettangolo andando incontro in alcuni casi ad effetti non voluti (se piazziamo il gadget ovale su un'immagine si osserveranno anche i quattro angoli del box del gadget). Per attivare il mascheramento bisogna inizializzare una struttura BoolInfo, il cui puntatore dovrà essere inserito nel campo SpecialInfo del gadget, e si dovrà attivare il flag GACT_BOOLEXTEND nel campo Activation sempre del gadget. Altra applicazione che potreste trovarvi davanti è la mutua esclusione dei gadgets; vale a dire una serie di gadget di tipo ToggleSelect raggruppati insieme, in cui la selezione di uno comporta la deselezione di tutti gli altri (necessario quando bisogna selezionare uno solo di una serie di serie di stati); questo tipo di applicazione non è gestita da intuition, per cui il programmatore dovrà arrangiarsi; ma non vi preoccupate perché arriva Zorro III il programmatore mascherato che vi salva e vi spiegherà come fare! I passi per implementare la mutua esclusione dei gadgets sono i seguenti: - i gadgets vanno creati di tipo ToggleSelect (impostando il flag GACT_TOGGLESELECT nel campo Action), con attivazione del solo tipo GACT_IMMEDIATE (non utilizzare quindi GACT_RELVERIFY), in tal maniera si gestiscono solo eventi IDCMP_GADGETDOWN - per l'illuminazione dei gadgets utilizzate una delle tecniche già viste - al verificarsi di un evento IDCMP_GADGETDOWN, dovranno essere rimossi i gadgets del blocco con un RemoveGList(), dovranno venir aggiustati gli stati di selezione mediante GFLF_SELECTED, quindi riagganciare i gadgets alla finestra mediante AddGList() e rivisualizzarli con RefreshGList(). I gadget proporzionali Spieghiamo ora come realizzare i gadget proporzionali; come già descritto la volta scorsa i gadget proporzionali permettono di specificare un valore in un possibile range, funzionano un po' come le manopole a slitta del volume di una radio; i gadget proporzionali sono costituiti da un contenitore (la cui grandezza corrisponde a quella del gadget) e da una manopola (knob) che scorre all'interno del contenitore; cliccando sulla manopola è possibile spostarsi fluidamente da un punto all'altro del range dei possibili valori; cliccando fuori dalla manopola ma sempre nel contenitore, si implementano spostamenti in blocco; i gadget proporzionali possono muoversi sull'asse x, y o entrambi e i movimenti hanno un limite teorico di 65536 posizioni, ma sono sempre limitati alla risoluzione dello schermo. Le applicazioni "logiche" dei gadget proporzionali sono sostanzialmente 2; la prima (denominata scroller) in cui si mostra normalmente un numero limitato di informazioni rispetto ad una grande quantità di dati; pensate ad esempio ad un text-editor, in tal caso la manopola rappresenta la posizione e la grandezza della "finestra" in cui vengono visualizzate le informazioni; in questo tipo di applicazione è importante anche la grandezza della manopola, perché rende l'idea della proporzione fra i dati visualizzati e quelli effettivamente disponibili. La seconda applicazione (denominata slider) impiega i gadget proporzionali per scegliere uno tra una serie di possibili valori (pensate alla manopola per il volume o per la scelte di una componente del colore). I due casi sono sostanzialmente differenti dal punto di vista del programmatore, nel primo infatti la manopola rappresenta un insieme di dati ma permette di spostarsi ugualmente di uno in uno, nel seconodo invece la manopola seleziona un solo elemento di una serie; tutti e due i casi sono realizzabili dai gadget proporzionali di Intuition, anzi se notate bene il secondo è un caso particolare del primo (basta impostare il numero di elementi visualizzati ad 1). Per realizzare un gadget proporzionale bisogna inizializzare una struttura ausiliaria, PropInfo il cui puntatore va inserito nel campo SpecialInfo del gadget; il primo campo da inizializzare è Flags, in cui è possibile specificare se non disegnare il bordo del gadget (PROPBORDERLESS, viene visualizzata solo la manopola); l'applicazione può specificare una propria immagine per la manopola o farne utilizzare una standard da Intuition (AUTOKNOB, l'immagine standard della manopola varia la propria grandezza in funzione di HorizBody e VertBody quindi risulta molto efficiente); bisogna comunque fornire una struttura Image anche se specificato AUTOKNOB (anche se in questo caso non c'è bisogno di inizializzare la struttura perché viene totalmente gestita da Intuition); la struttura Image non può essere condivisa da altri gadget proporzionali. Bisogna indicare in che direzione si può muovere la manopola, orizzontalmente (FREEHORIZ) e/o verticalmente (FREEVERT); anche i gadget proporzionali come tutto il resto del sistema ha cambiato il suo look in uno 3D molto più accattivante, per attivarlo (fatelo sempre) utilizzare il flag PROPNEWLOOK. Altre variabili del PropInfo da inizializzare sono HorizPot e VertPot che indicano la posizione della manopola; questi valori vanno da 0 (posizione minima) a MAXPOT-body (posizione massima), dove body è la grandezza della manopola (che equivale al numero di elementi visualizzati) per cui occorre effettuare una proporzione per calcolare il giusto valore: pot = ((val - minval) * MAXPOT) / ((maxval - minval) - numval); dove minval è il valore minimo che la manopola può assumere, maxval è il suo valore massimo, numval è il numero di elementi visualizzati; val è il valore attualmente assunto dalla manopola e pot è il valore da inserire in HorizPot e/o VertPot; vediamo un esempio per fissare meglio l'idea: immaginiamo che la manopola debba specificare la componente Rosso (range 0 - 255) con un valore iniziale di 170: UWORD pot; struct PropInfo PI; . . pot = ((170 - 0) * MAXPOT) / ((255 - 0) - 1); PI.HorizPot = pot; /* e, oppure */ PI.VertPot = pot; La conversione va fatta naturalmente anche quando bisogna leggere il valore della posizione in HorizPot o VertPot per sapere quale elemento (o gruppo) è stato selezionato con il gadget; la formula è la seguente: val = (pot * ((maxval - minval) - 1)) / MAXPOT + minval; dove pot è il valore prelevato da HorizPot o VertPot e le altre variabili assumono lo stesso significato prima descritto; verifichiamo l'esempio precedente: UBYTE Red; struct PropInfo PI; . . Red = (PI.Horiz.Pot * ((255 - 0) - 1)) / MAXPOT + 0; Gli altri due campi da inizializzare ed usare sono HorizBody e VertBody che indicano l'ampiezza e l'altezza della manopola; se è stato specificato AUTOKNOB nel campo Flags, l'immagine della manopola cambierà la propria dimensione in base a questi campi; come i Pot anche i Body variano da 0 a MAXBODY, per cui bisogna utilizzare delle proporzioni simili a quelle viste: body = (numval * MAXBODY) / (maxval - minval); dove numval è il numero di elementi o range visualizzato. Le formule prima citate valgono sia per gli scrollers che per gli sliders, bisogna fare attenzione che nel primo caso "val" (l'elemento puntato dalla manopola) indichi il primo elemento visualizzato nella pagina, mentre per gli sliders occorre utilizzare come numval 1. Per creare un gadget proporzionale occorre specificare GTYP_PROPGADGET nel campo GadgetType della struttura Gadget e inserire il puntatore alla struttura PropInfo nel campo SpecialInfo della struttura Gadget; ripetieamo che quando si utilizza AUTOKNOB, bisogna far attenzione ad inserire l'indirizzo di una struttura Image creata (non c'è bisogno di inizializzarla e gestirla, in quanto questo sarà compito di Intuition) nel campo GadgetRender della struttura Gadget (attenzione a non impostare il flag GFLG_GADGIMAGE). Per utilizzare una propria immagine basta semplicemente non specificare AUTOKNOB nel PropInfo ed indicare GFLG_GADGIMAGE nel Gadget; se si vuole inoltre utilizzare l'immagine per l'illuminazione o selezione del gadget bisogna impostare il flag GFLG_GADGHIMAGE e fornire il puntatore alla struttura Image (che deve avere stesse dimensioni di quella per l'immagine non selezionata). Per modificare i valori (flag, posizione e grandezza della manopola) senza bisogno di staccare il gadget dal sistema, si utilizza la funzione NewModifyProp(): NewModifyProp(gadget,finestra,requester,flags,horizpot,vertpot,horizbody,vertbody,numgad); dove gadget è il gadget proporzionale di cui cambiare i valori, finestra è il puntatore alla finestra in cui il gadget è inserito, requester è il puntatore al requester se invece il gadget è inserito in un requester, flags, horizpot, vertpot, horizbody, vertbody sono i nuovi valori del PropInfo; numgad è il codice di posizione in cui reinserire il gadget dopo che è stato deinserito e aggiornato dalla funzione; si può impostare questo valore a tutti 1 (dato che è un long quindi il valore è 0xFFFFFFFF) e in questa maniera, la funzione aggiornerà le parti dell'immagine che sono effettivamente modificate, ciò risulta notevolmente più veloce quindi è consigliabile. I gadget stringa I gadget stringa permettono di inserire una stringa di caratteri; una volta selezionato il gadget, intuition visualizzerà il cursore per inserire nuovi caratteri; il cursore può essere spostato con i tasti cursore e con l'intervento del mouse; quando l'utente preme il tasto RETURN o ENTER oppure seleziona da qualche altra parte, allora il gadget è deselezionato. Quando l'utente preme RETURN o ENTER viene generato un messaggio di tipo IDCMP_GADGETUP se era specificato GACT_RELVERIFY; se il gadget viene deselezionato cliccando altrove, allora non viene generato nessun messaggio IDCMP_GADGETUP. Il gadget può permettere di inserire anche solo un valore numerico a 32 bit segnato(gadget stringa Integer); per impostare il gadget stringa di tipo Integer, bisogna impostare il flag GACT_LONGINT nel campo Activation del gadget; il valore numerico inserito è presente nel campo LongInt della struttura StringInfo associata al gadget stringa. E' possibile attivare il gadget stringa da applicazione mediante la funzione: BOOL ActivateGadget(gadget, finestra, requester); dove gadget è il gadget stringa da attivare, finestra è il puntatore alla finestra a cui appartiene e requester è il puntatore al requester se il gadget è inserito in un requester. Non è detto che l'operazione possa avere successo; questo perché nel frattempo il sistema potrebbe essere impegnato con un menù o con altre operazioni; se l'operazione di attivazione ha successo, allora ActivateGadget() ritorna TRUE e FALSE altrimenti. Vi è la possibilità dalla V37 del sistema, di passare da un gadget stringa ad un altro premendo TAB o SHIFT+TAB; per abilitare il vostro gadget stringa ad entrare in questo ciclo di selezione, occorre inserire il flag GFLG_TABCYCLE; l'ordine di selezione sarà determinato dalla posizione dei gadgets nella lista; se un gadget viene deselezionato con un TAB, Intuition invierà un messaggio IDCMP_GADGETUP all'applicazione (come se si fosse premuto RETURN o ENTER); per capire che la deselezione è dovuta alla pressione del tasto TAB, si può controllare il campo Code del messaggio che conterrà il valore 0x09 (il codice ASCII del TAB). Per realizzare un gadget stringa, bisogna inizializzare una struttura StringInfo, passarne l'indirizzo nel campo SpecialInfo del gadget e specificare il flag GTYP_STRGADGET nel campo GadgetType; l'applicazione può indicare l'allineamento della stringa, mediante GACT_STRINGLEFT, GACT_STRINGCENTER o GACT_STRINGRIGHT. Per il rendering del gadget stringa, si può utilizzare uno qualsiasi dei metodi visti, mentre per l'illuminazione si deve specificare necessariamente il complemento (GFLG_GADGHCOMP).